package org.edu.eece262.taskshare;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.edu.eece262.taskshare.ContactsDBAdapter.StatusType;
import org.edu.eece262.taskshare.Messages.ActionType;
import org.edu.eece262.taskshare.Messages.Group;
import org.edu.eece262.taskshare.Messages.MessageToClient;
import org.edu.eece262.taskshare.Messages.MessageToServer;
import org.edu.eece262.taskshare.Messages.ResponseType;
import org.edu.eece262.taskshare.Messages.Task;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.util.Log;
import android.widget.Toast;

public class HTTPHelp {
	
	// Let's be a Singleton
	private static HTTPHelp instanceActivity = null;
	private static HTTPHelp instanceService = null;
	private final String URL = "http://androidtaskshare.appspot.com/android";
									//"http://10.0.2.2:8888/android";
	
	public static final String PREFS_NAME = "TASKSHARELOGIN";
	
	private String username;
	private String password;
	private boolean loggedIn = false;
	private String UUID;
	Gson gson;
	DefaultHttpClient httpClient;
	
	public static HTTPHelp getActivityHTTPHelp() {
		if (instanceActivity == null) {
			instanceActivity = new HTTPHelp();
			return instanceActivity;
		} else {
			return instanceActivity;
		}
	}
	
	public static HTTPHelp getServiceHTTPHelp() {
		if (instanceService == null) {
			instanceService = new HTTPHelp();
			return instanceService;
		} else {
			return instanceService;
		}
	}
	
	private HTTPHelp() {
		gson = new Gson();
		httpClient = new DefaultHttpClient();
	}
	
	public boolean createUser(String username, String password, String email, String phone, String name) {
		MessageToClient received = notLoggedInPost(new Messages.MessageToServer()
				.setAction(ActionType.CREATEUSER)
				.setUser(username)
				.setPassword(password)
				.setPhone_number(phone)
				.setEmail(email)
				.setName(name)
				.setAccess_level(2));
		if (received == null) {
			return false;
		} else if (received.getResponse() == ResponseType.SUCCESS) {
			return true;
		} else {
			return false;
		}
	}

	public boolean logIn(String username, String password) {
		MessageToClient received = notLoggedInPost(new Messages.MessageToServer()
			.setResponse(ResponseType.SUCCESS)
			.setUser(username)
			.setPassword(password)
			.setAction(ActionType.LOGIN));
		if (received == null) {
			loggedIn = false;
			return false;
		} else if (received.getResponse() == ResponseType.SUCCESS) {
			loggedIn = true;
			this.username = username;
			this.password = password;
			this.UUID = received.getUuid();
			return true;
		} else {
			loggedIn = false;
			return false;
		}
	}

	public boolean pollServer(Context context) {
		SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
		MessageToServer sendMe = new MessageToServer().setAction(ActionType.POLL).setUser(username).setLastModifiedTime(settings.getLong(username + "lastmodified", 0));
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		
		if(messageToClient != null && messageToClient.getResponse() == ResponseType.SUCCESS) {
			SharedPreferences.Editor editor = settings.edit();
			editor.putLong(username + "lastmodified", messageToClient.getLastModified());
			editor.commit();
			// Contacts
			// - Added
			LinkedList<Messages.User> addedContacts = messageToClient.getAddedContacts();
			if(addedContacts != null) {
				for(int i = 0; i < addedContacts.size(); i++) {
					ContactsDBAdapter contactsDBA = ContactsDBAdapter.getContactsDBAdapter(context);
					contactsDBA.open();
					Cursor localResults = contactsDBA.getEntriesMatching(addedContacts.get(i).getUsername());
					if(localResults.getCount() > 0) {
						localResults.moveToFirst();
						while(!localResults.isAfterLast()) {
							contactsDBA.updateStatus(localResults.getInt(0), StatusType.ACTIVE);
							localResults.moveToNext();
						}
					} else {
						Messages.User cur = addedContacts.get(i);
						contactsDBA.insertUser(cur.getUsername(), 
								cur.getName(), cur.getEmail(), 
								cur.getPhonenumber(), StatusType.ACTIVE);
					}
					contactsDBA.close();
				}
			}
			// - Requested
			LinkedList<Messages.User> requestedContacts = messageToClient.getRequestedContacts();
			if(requestedContacts != null) {
				for(int i = 0; i < requestedContacts.size(); i++) {
					ContactsDBAdapter contactsDBA = ContactsDBAdapter.getContactsDBAdapter(context);
					contactsDBA.open();
					Cursor localResults = contactsDBA.getEntriesMatching(requestedContacts.get(i).getUsername());
					if(localResults.getCount() > 0) {
						localResults.moveToFirst();
						while(!localResults.isAfterLast()) {
							if(localResults.getInt(ContactsDBAdapter.STATUS_COLUMN) != StatusType.ACTIVE) {
								contactsDBA.updateStatus(localResults.getInt(0), StatusType.REQUESTED);
							}
							localResults.moveToNext();
						}
					} else {
						Messages.User cur = requestedContacts.get(i);
						contactsDBA.insertUser(cur.getUsername(), 
								cur.getName(), cur.getEmail(), 
								cur.getPhonenumber(), StatusType.REQUESTED);
					}
					contactsDBA.close();
				}
			}
			// - Deleted
			LinkedList<Messages.User> deletedContacts = messageToClient.getRemovedContacts();
			if(deletedContacts != null) {
				for(int i = 0; i < deletedContacts.size(); i++) {
					ContactsDBAdapter contactsDBA = ContactsDBAdapter.getContactsDBAdapter(context);
					contactsDBA.open();
					Cursor localResults = contactsDBA.getEntriesMatching(deletedContacts.get(i).getUsername());
					localResults.moveToFirst();
					while(!localResults.isAfterLast()) {
						contactsDBA.removeEntry(localResults.getInt(0));
						localResults.moveToNext();
					}
					contactsDBA.close();
				}
			}
			LinkedList<Task> tasks = messageToClient.getTasks();
			if(tasks != null) {
				Log.e("POLL", "Doing tasks...");
				TaskDBAdapter taskDBA = TaskDBAdapter.getTSDBAdapter(context);
				for(int i = 0; i < tasks.size(); i++) {
					if(taskDBA.getTaskWithGlobalID(tasks.get(i).getGlobal_id()).getCount() > 0) {
						Log.e("POLL", "UPDATE");
						taskDBA.updateEntryFromGlobal(tasks.get(i).getLocal_id(), tasks.get(i).getGlobal_id(), 
								tasks.get(i).getName(), tasks.get(i).getOwner(), tasks.get(i).getAssignedList(), 
								tasks.get(i).getNotes(), tasks.get(i).getLocation(), tasks.get(i).getGlobal_parent(), 
								tasks.get(i).getDue_date(), tasks.get(i).getDue_time(), tasks.get(i).getPercent_complete(), 
								tasks.get(i).getPriority(), tasks.get(i).getTimestamp());
					} else {
						Log.e("POLL", "INSERT");
						taskDBA.insertEntryFromGlobal(tasks.get(i).getLocal_id(), tasks.get(i).getGlobal_id(), 
								tasks.get(i).getName(), tasks.get(i).getOwner(), tasks.get(i).getAssignedList(), 
								tasks.get(i).getNotes(), tasks.get(i).getLocation(), tasks.get(i).getGlobal_parent(), 
								tasks.get(i).getDue_date(), tasks.get(i).getDue_time(), tasks.get(i).getPercent_complete(), 
								tasks.get(i).getPriority(), tasks.get(i).getTimestamp());
					}
				}	
			}
			
			//Groups
			if(messageToClient.getGroups() != null) {
				for(int i = 0; i < messageToClient.getGroups().size(); i++) {
					GroupDBAdapter.getGroupDBA(context).updateOrCreateFromGlobal(messageToClient.getGroups().get(i));
				}
			}
			return true;
		}
		return false;
	}
	
	public boolean createGroup(String name, LinkedList<Messages.GroupMember> members, Context context) {
		SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
		String user = settings.getString("user", "");
		
		MessageToServer sendMe = new MessageToServer()
			.setAction(ActionType.CREATEGROUP)
			.setUser(user)
			.setGroup(new Group()
				.setOwner(user)
				.setGroupName(name)
				.setMembers(members)
				.setGroupDeleted(false));
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		
		if(messageToClient.getResponse() == ResponseType.SUCCESS)
			return true;
		else
			return false;
	}
	
	public boolean updateGroup(String name, String owner, LinkedList<Messages.GroupMember> members, Context context) {
		SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
		String user = settings.getString("user", "");
		
		MessageToServer sendMe = new MessageToServer()
			.setAction(ActionType.MODIFYGROUP)
			.setUser(user)
			.setGroup(new Group()
				.setOwner(owner)
				.setGroupName(name)
				.setMembers(members)
				.setGroupDeleted(false));
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		
		if(messageToClient.getResponse() == ResponseType.SUCCESS) {
			GroupDBAdapter.getGroupDBA(context).updateOrCreateFromGlobal(messageToClient.getGroups().get(0));
			return true;
		} else {
			return false;
		}
	}
	
	public boolean assignToGroupOneShot(int localID, String groupName, Context context) {
		SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
		String user = settings.getString("user", "");
		
		Cursor task = TaskDBAdapter.getTSDBAdapter(context).getTaskWithLocalID(localID);
		Cursor group = GroupDBAdapter.getGroupDBA(context).getGroupWithName(groupName);
		
		if(task.getCount() < 1 || group.getCount() < 1) {
			return false;
		} else {
			task.moveToFirst();
			group.moveToFirst();
			
			MessageToServer sendMe = new MessageToServer()
				.setAction(ActionType.ASSIGNTOGROUPONESHOT)
				.setUser(user)
				.setGroup(new Group()
					.setOwner(group.getString(GroupDBAdapter.OWNER_COLUMN))
					.setGroupName(group.getString(GroupDBAdapter.NAME_COLUMN))
					.setMembers(GroupDBAdapter.groupMembersFromCursor(group))
					.setGroupDeleted(false))
				.addTask(new Task()
					.setGlobal_id(task.getLong(TaskDBAdapter.GLOBAL_ID_COLUMN))
					.setName(task.getString(TaskDBAdapter.NAME_COLUMN))
					.setNotes(task.getString(TaskDBAdapter.NOTES_COLUMN))
					.setLocation(task.getString(TaskDBAdapter.LOCATION_COLUMN))
					.setGlobal_parent(task.getLong(TaskDBAdapter.PARENT_GLOBAL_COLUMN))
					.setDue_date(task.getInt(TaskDBAdapter.DUE_DATE_COLUMN))
					.setDue_time(task.getInt(TaskDBAdapter.DUE_TIME_COLUMN))
					.setPercent_complete(task.getInt(TaskDBAdapter.PERCENT_COMPLETE_COLUMN))
					.setPriority(task.getInt(TaskDBAdapter.PRIORITY_COLUMN))
					.setDone(task.getInt(TaskDBAdapter.DONE_COLUMN))
					.setLocal_id(task.getInt(0)));
			
			MessageToClient messageToClient = loggedInPost(sendMe, false);
			
			if(messageToClient.getResponse() == ResponseType.SUCCESS) {
				Task curTask = messageToClient.getTasks().get(0);
				TaskDBAdapter.getTSDBAdapter(context).updateEntryFromGlobal(curTask.getLocal_id(), curTask.getGlobal_id(), curTask.getName(), 
						curTask.getOwner(), curTask.getAssignedList(),
						curTask.getNotes(), curTask.getLocation(), curTask.getGlobal_parent(), 
						curTask.getDue_date(), curTask.getDue_time(), curTask.getPercent_complete(), 
						curTask.getPriority(), curTask.getTimestamp());
				return true;
			} else {
				return false;
			}
		}
	}
	
	public boolean assignToGroupMultipleCompletion(int localID, String groupName, Context context) {
		SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
		String user = settings.getString("user", "");
		
		Cursor task = TaskDBAdapter.getTSDBAdapter(context).getTaskWithLocalID(localID);
		Cursor group = GroupDBAdapter.getGroupDBA(context).getGroupWithName(groupName);
		
		if(task.getCount() < 1 || group.getCount() < 1) {
			return false;
		} else {
			task.moveToFirst();
			group.moveToFirst();
			
			MessageToServer sendMe = new MessageToServer()
				.setAction(ActionType.ASSIGNTOGROUPMULTIPLECOMPLETION)
				.setUser(user)
				.setGroup(new Group()
					.setOwner(group.getString(GroupDBAdapter.OWNER_COLUMN))
					.setGroupName(group.getString(GroupDBAdapter.NAME_COLUMN))
					.setMembers(GroupDBAdapter.groupMembersFromCursor(group))
					.setGroupDeleted(false))
				.addTask(new Task()
					.setGlobal_id(task.getLong(TaskDBAdapter.GLOBAL_ID_COLUMN))
					.setName(task.getString(TaskDBAdapter.NAME_COLUMN))
					.setNotes(task.getString(TaskDBAdapter.NOTES_COLUMN))
					.setLocation(task.getString(TaskDBAdapter.LOCATION_COLUMN))
					.setGlobal_parent(task.getLong(TaskDBAdapter.PARENT_GLOBAL_COLUMN))
					.setDue_date(task.getInt(TaskDBAdapter.DUE_DATE_COLUMN))
					.setDue_time(task.getInt(TaskDBAdapter.DUE_TIME_COLUMN))
					.setPercent_complete(task.getInt(TaskDBAdapter.PERCENT_COMPLETE_COLUMN))
					.setPriority(task.getInt(TaskDBAdapter.PRIORITY_COLUMN))
					.setDone(task.getInt(TaskDBAdapter.DONE_COLUMN))
					.setLocal_id(task.getInt(0)));
			
			MessageToClient messageToClient = loggedInPost(sendMe, false);
			
			if(messageToClient.getResponse() == ResponseType.SUCCESS) {
				for(int i = 0; i < messageToClient.getTasks().size(); i++) {
					Task curTask = messageToClient.getTasks().get(i);
					TaskDBAdapter.getTSDBAdapter(context).updateEntryFromGlobal(curTask.getLocal_id(), curTask.getGlobal_id(), curTask.getName(), 
							curTask.getOwner(), curTask.getAssignedList(),
							curTask.getNotes(), curTask.getLocation(), curTask.getGlobal_parent(), 
							curTask.getDue_date(), curTask.getDue_time(), curTask.getPercent_complete(), 
							curTask.getPriority(), curTask.getTimestamp());
				}
				return true;
			} else {
				return false;
			}
		}
	}
	
	public LinkedList<Messages.Group> searchGroups(String groupName, Context context) {
		SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
		String user = settings.getString("user", "");
		
		MessageToServer sendMe = new MessageToServer()
		.setAction(ActionType.SEARCHGROUPS)
		.setUser(user)
		.setGroup(new Group()
			.setGroupName(groupName));
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		
		return messageToClient.getGroups();
	}
	
	public void joinGroup(String groupName, Context context) {
		SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
		String user = settings.getString("user", "");
		
		MessageToServer sendMe = new MessageToServer()
		.setAction(ActionType.JOINGROUP)
		.setUser(user)
		.setGroup(new Group()
			.setGroupName(groupName));
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		
		if(messageToClient.getResponse() == ResponseType.ONHOLD) {
			Toast.makeText(context, "Request sent.", Toast.LENGTH_LONG);
		} else if(messageToClient.getResponse() == ResponseType.SUCCESS) {
			Toast.makeText(context, "Membership active.", Toast.LENGTH_LONG);
		} else {
			Toast.makeText(context, "Failure.", Toast.LENGTH_LONG);
		}
	}

	public boolean deleteGroup(String groupName, Context context) {
		SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
		String user = settings.getString("user", "");
		
		Cursor group = GroupDBAdapter.getGroupDBA(context).getGroupWithName(groupName);
		
		if(group.getCount() < 0) {
			return false;
		}
		
		group.moveToFirst();
		
		MessageToServer sendMe = new MessageToServer()
			.setAction(ActionType.DELETEGROUP)
			.setUser(user)
			.setGroup(new Group()
				.setOwner(user)
				.setGroupName(groupName)
				.setMembers(GroupDBAdapter.groupMembersFromCursor(group))
				.setGroupDeleted(false));
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		
		if(messageToClient.getResponse() == ResponseType.SUCCESS) {
			GroupDBAdapter.getGroupDBA(context).deleteGroup(groupName, context);
			return true;
		} else {
			return false;
		}
	}
	
	public boolean createTask(Task task, String user, Context context) {
		MessageToServer sendMe = new MessageToServer()
			.setAction(ActionType.ADDTASK)
			.setUser(user)
			.addTask(task);
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		if(messageToClient != null && 
				messageToClient.getResponse() == ResponseType.SUCCESS) {
			LinkedList<Messages.Task> tasks = messageToClient.getTasks();
			for(int i = 0; i < tasks.size(); i++) {
				TaskDBAdapter taskDBA = TaskDBAdapter.getTSDBAdapter(context);
				Task curTask = tasks.get(0);
				taskDBA.updateNewEntryFromGlobal(curTask.getLocal_id(), curTask.getGlobal_id(), curTask.getName(), messageToClient.getUser()
						, curTask.getAssignedList(), curTask.getNotes(), curTask.getLocation(), curTask.getGlobal_parent(), 
						curTask.getDue_date(), curTask.getDue_time(), curTask.getPercent_complete(), 
						curTask.getPriority(), curTask.getTimestamp());
			}
			
			return true;
		} else { 
			return false;
		}
	}
	
	public boolean updateTask(Task task, String user, Context context) {
		MessageToServer sendMe = new MessageToServer()
			.setAction(ActionType.UPDATETASK)
			.setUser(user)
			.addTask(task);
		Log.e("TASK SHARE GLOBAL", ""+task.getGlobal_id());
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		if(messageToClient != null && 
				messageToClient.getResponse() == ResponseType.SUCCESS) {
			LinkedList<Messages.Task> tasks = messageToClient.getTasks();
			for(int i = 0; i < tasks.size(); i++) {
				TaskDBAdapter taskDBA = TaskDBAdapter.getTSDBAdapter(context);
				Task curTask = tasks.get(0);
				taskDBA.updateEntryFromGlobal(curTask.getLocal_id(), curTask.getGlobal_id(), curTask.getName(), 
						curTask.getOwner(), curTask.getAssignedList(),
						curTask.getNotes(), curTask.getLocation(), curTask.getGlobal_parent(), 
						curTask.getDue_date(), curTask.getDue_time(), curTask.getPercent_complete(), 
						curTask.getPriority(), curTask.getTimestamp());
			}
			return true;
		} else { 
			return false;
		}
	}
	
	@SuppressWarnings("unchecked")
	public void assignTask(int localID, LinkedList<String> Assignees, Context context) {
		SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
		String user = settings.getString("user", "");
		TaskDBAdapter taskDBA = TaskDBAdapter.getTSDBAdapter(context);
		Cursor current = taskDBA.getTaskWithLocalID(localID);
		current.moveToFirst();
		
		Type collectionType = new TypeToken<LinkedList<String>>(){}.getType();
		
		Task task = new Task()
			.setGlobal_id(current.getLong(TaskDBAdapter.GLOBAL_ID_COLUMN))
			.setName(current.getString(TaskDBAdapter.NAME_COLUMN))
			.setNotes(current.getString(TaskDBAdapter.NOTES_COLUMN))
			.setLocation(current.getString(TaskDBAdapter.LOCATION_COLUMN))
			.setGlobal_parent(current.getLong(TaskDBAdapter.PARENT_GLOBAL_COLUMN))
			.setDue_date(current.getInt(TaskDBAdapter.DUE_DATE_COLUMN))
			.setDue_time(current.getInt(TaskDBAdapter.DUE_TIME_COLUMN))
			.setPercent_complete(current.getInt(TaskDBAdapter.PERCENT_COMPLETE_COLUMN))
			.setPriority(current.getInt(TaskDBAdapter.PRIORITY_COLUMN))
			.setDone(current.getInt(TaskDBAdapter.DONE_COLUMN))
			.setAssignedList((LinkedList<String>) gson.fromJson(current.getString(TaskDBAdapter.ASSIGNED_LIST_COLUMN), collectionType))
			.setLocal_id(current.getInt(0));
		
		LinkedList<String> failedUsers = new LinkedList<String>();
		
		if(!current.isAfterLast()) {
			LinkedList<String> oldAssignees = gson.fromJson(current.getString(TaskDBAdapter.ASSIGNED_LIST_COLUMN), collectionType);
			for(int i = 0; i < Assignees.size(); i++) {
				if(!oldAssignees.contains(Assignees.get(i))) {
					if(!assignTask(task, user, Assignees.get(i), context)) {
						failedUsers.add(Assignees.get(0));
					}
						
				}
			}
			
			if(failedUsers.size() > 0) {
				String failure = "Reassignment(s) failed: ";
				for(int i = 0; i < failedUsers.size(); i++) {
					failure = failure + failedUsers.get(i);
					if(i != failedUsers.size() - 1)
						failure = failure + ", ";
				}
				Toast.makeText(context, failure, Toast.LENGTH_LONG);
			}
		} else {
			Toast.makeText(context, "Task not found.", Toast.LENGTH_SHORT).show();
		}
		
	}
	
	public boolean assignTask(Task task, String user, String contact_user, Context context) {
		MessageToServer sendMe = new MessageToServer()
			.setAction(ActionType.ASSIGNTASK)
			.setUser(user)
			.setContact_user(contact_user)
			.addTask(task);
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		if(messageToClient != null && 
				messageToClient.getResponse() == ResponseType.SUCCESS) {
			LinkedList<Messages.Task> tasks = messageToClient.getTasks();
			for(int i = 0; i < tasks.size(); i++) {
				TaskDBAdapter taskDBA = TaskDBAdapter.getTSDBAdapter(context);
				Task curTask = tasks.get(0);
				taskDBA.updateEntryFromGlobal(curTask.getLocal_id(), curTask.getGlobal_id(), curTask.getName(),
						curTask.getOwner(), curTask.getAssignedList(),
						curTask.getNotes(), curTask.getLocation(), curTask.getGlobal_parent(), 
						curTask.getDue_date(), curTask.getDue_time(), curTask.getPercent_complete(), 
						curTask.getPriority(), curTask.getTimestamp());
			}
			
			return true;
		} else { 
			return false;
		}
	}
	
	public boolean deleteTask(Task task, String user, Context context) {
		MessageToServer sendMe = new MessageToServer()
			.setAction(ActionType.DELETETASK)
			.setUser(user)
			.addTask(task);
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		if(messageToClient != null && 
				messageToClient.getResponse() == ResponseType.SUCCESS) {
			LinkedList<Messages.Task> tasks = messageToClient.getTasks();
			for(int i = 0; i < tasks.size(); i++) {
				TaskDBAdapter taskDBA = TaskDBAdapter.getTSDBAdapter(context);
				Task curTask = tasks.get(i);
				taskDBA.removeEntryByGlobal(curTask.getGlobal_id());
			}
			
			return true;
		} else { 
			return false;
		}
	}
	
	public LinkedList<Messages.User> searchUser(String query, Context context) {
		LinkedList<Messages.User> returnValue = null;
		MessageToServer sendMe = new MessageToServer()
			.setAction(ActionType.SEARCHCONTACT)
			.setContact_user(query)
			.setUser(query)
			.setUuid(UUID);
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		if(messageToClient != null && 
			messageToClient.getResponse() == ResponseType.SUCCESS) {
			returnValue = messageToClient.getUsers();
			if(returnValue.isEmpty())
				Log.e("CONTACTSEARCH","No users returned.");
		}
		return returnValue;
	}

	public boolean requestContact(Messages.User user, Context context) {
		ContactsDBAdapter contactsDBA = ContactsDBAdapter.getContactsDBAdapter(context);
		contactsDBA.open();
		Cursor current = contactsDBA.getEntriesMatching(user.getUsername());
		long row = 0;
		if(current.getCount() > 0) {
			current.moveToFirst();
			row = current.getInt(0);
		} else {
			row = contactsDBA.insertUser(user.getUsername(), user.getName(), user.getEmail(), 
					user.getPhonenumber(), ContactsDBAdapter.StatusType.WAITING);
		}
		MessageToServer sendMe = new MessageToServer()
			.setAction(ActionType.ADDCONTACT)
			.setContact_user(user.getUsername())
			.setUser(username);
		MessageToClient messageToClient = loggedInPost(sendMe, false);
		if(messageToClient.getResponse() == ResponseType.SUCCESS) {
			contactsDBA.updateEntry((int)row, user.getUsername(), user.getName(), user.getEmail(), 
					user.getPhonenumber(), ContactsDBAdapter.StatusType.ACTIVE);
			contactsDBA.close();
			return true;
		} else if(messageToClient.getResponse() == ResponseType.ONHOLD) {
			contactsDBA.close();
			return true;
		} else {
			contactsDBA.close();
			return false;
		}
	}
	
	public boolean deleteContact(Messages.User user, Context context) {
		ContactsDBAdapter contactsDBA = ContactsDBAdapter.getContactsDBAdapter(context);
		contactsDBA.open();
		Cursor localResults = contactsDBA.getEntriesMatching(user.getUsername());
		localResults.moveToFirst();
		while(!localResults.isAfterLast()) {
			contactsDBA.updateEntry(localResults.getInt(0), 
					localResults.getString(ContactsDBAdapter.USER_NAME_COLUMN), 
					localResults.getString(ContactsDBAdapter.NAME_COLUMN),
					localResults.getString(ContactsDBAdapter.EMAIL_COLUMN), 
					localResults.getString(ContactsDBAdapter.PHONE_COLUMN), 
					StatusType.DELETED);
			localResults.moveToNext();
		}
		MessageToServer sendMe = new MessageToServer()
		.setAction(ActionType.DELETECONTACT)
		.setContact_user(user.getUsername())
		.setUser(username);
		loggedInPost(sendMe, false);
		
		contactsDBA.close();
		return true;
	}
	
	public MessageToClient notLoggedInPost(MessageToServer sendMe) {
		DefaultHttpClient httpClient = new DefaultHttpClient();

		HttpPost postMethod = new HttpPost(URL);

		List <NameValuePair> postData = new ArrayList <NameValuePair>();
        postData.add(new BasicNameValuePair("JSONMessageToServer", gson.toJson(sendMe)));
		

		Messages.MessageToClient mtcResponse = null;

		try {
			postMethod.setEntity(new UrlEncodedFormEntity(postData));

			HttpResponse response = httpClient.execute(postMethod);
			
			String JSONMessageToClient = convertStreamToString(response.getEntity().getContent());
			Log.e("HTTP RESULTS", JSONMessageToClient);
			mtcResponse = gson.fromJson(JSONMessageToClient, Messages.MessageToClient.class);
			Log.e("HTTP RESPONSE", mtcResponse.toString());
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			Log.e("HTTP ERROR ", "Unsupported encoding.");
		} catch (HttpResponseException e) {
			e.printStackTrace();
			Log.e("HTTP ERROR CODE", "" + e.getStatusCode());
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			Log.e("HTTP ERROR ", "Protocol exception.");
		} catch (IOException e) {
			e.printStackTrace();
			Log.e("HTTP ERROR ", "General IO Exception.");
		}

		return mtcResponse;

	}
	
	public MessageToClient loggedInPost(MessageToServer sendMe, boolean secondTry) {
		if(!loggedIn && username != null && password != null) {
			logIn(username, password);
		}
		
		if (loggedIn) {
			sendMe.setUser(username);
			sendMe.setUuid(UUID);
			
			HttpPost postMethod = new HttpPost(URL);
	
			List <NameValuePair> postData = new ArrayList <NameValuePair>();
	        postData.add(new BasicNameValuePair("JSONMessageToServer", gson.toJson(sendMe)));
			
	
			Messages.MessageToClient mtcResponse = null;
	
			try {
				postMethod.setEntity(new UrlEncodedFormEntity(postData));
				
				HttpResponse response = httpClient.execute(postMethod);
				
				String JSONMessageToClient = convertStreamToString(response.getEntity().getContent());
				Log.e("HTTP RESULTS", JSONMessageToClient);
				mtcResponse = gson.fromJson(JSONMessageToClient, Messages.MessageToClient.class);
				
				if((mtcResponse.getResponse() == ResponseType.FAILURENOTLOGGEDIN) && !secondTry) {
					logIn(username, password);
					return loggedInPost(sendMe, true);
				} else {
					loggedIn = false;
				}
				
				Log.e("HTTP RESPONSE", mtcResponse.toString());
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				Log.e("HTTP ERROR ", "Unsupported encoding.");
			} catch (HttpResponseException e) {
				e.printStackTrace();
				Log.e("HTTP ERROR CODE", "" + e.getStatusCode());
			} catch (ClientProtocolException e) {
				e.printStackTrace();
				Log.e("HTTP ERROR ", "Protocol exception.");
			} catch (IOException e) {
				e.printStackTrace();
				Log.e("HTTP ERROR ", "General IO Exception.");
			}
	
			return mtcResponse;
		} else {
			return null;
		}

	}
	
    public static String convertStreamToString(InputStream is) throws IOException {
        if (is != null) {
            StringBuilder sb = new StringBuilder();
            char[] buf = new char[1];

            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                while (reader.read(buf) != -1) {
                    sb.append(buf);
                }
            } finally {
                is.close();
            }
            return sb.toString();
        } else {        
            return "";
        }
    }

	
    public boolean isLoggedIn() {
		return loggedIn;
	}
}